package org.tech4j.springboot.starter.distributedlock.api.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tech4j.springboot.starter.distributedlock.api.ILock;

import java.util.concurrent.TimeUnit;

/**
 * @program: tech4j
 * @description:
 * @author: YuKai Fan
 * @create: 2023/2/19 22:36
 **/
public class LockUtils {
    private static final Logger log = LoggerFactory.getLogger(LockUtils.class);
    private static ILock lock;

    public static void setLock(ILock lock) {
        LockUtils.lock = lock;
    }


    /**
     * @param lockKey:分布式锁key
     * @description 获取锁，获取失败则一直等待
     */
    public static void lock(String lockKey) {
        log.info("lock lockKey[{}]", lockKey);
        lock.lock(lockKey);
    }


    /**
     * @param lockKey:分布式锁key
     * @param waitTime:锁等待时间
     * @return boolean 返回结果
     * @description 获取锁，获取失败则一直等待
     */
    public static void lock(String lockKey, long waitTime) {
        log.info("lock lockKey[{}] waitTime[{}]", lockKey, waitTime);
        lock.lock(lockKey, waitTime, TimeUnit.SECONDS);
    }

    /**
     * @param lockKey:分布式锁key
     * @return boolean 返回结果
     * @description 尝试获取锁，获取到立即返回true,获取失败立即返回false，默认锁过期时间30S
     */
    public static boolean tryLock(String lockKey) {
        log.info("tryLock lockKey[{}]", lockKey);
        boolean result = lock.tryLock(lockKey);
        log.info("tryLock lockKey[{}] result is [{}]", lockKey, result);
        return result;
    }

    /**
     * @param lockKey:分布式锁key
     * @param waitTime:锁等待时间
     * @return boolean 返回结果
     * @description 尝试获取锁，waitTime时间内获取到返回true,获取失败返回false
     */
    public static boolean tryLock(String lockKey, long waitTime) {
        try {
            log.info("tryLock lockKey[{}] waitTime[{}]", lockKey, waitTime);
            boolean result = lock.tryLock(lockKey, waitTime, TimeUnit.SECONDS);
            log.info("tryLock lockKey[{}] waitTime[{}] result[{}]", lockKey, waitTime, result);
            return result;
        } catch (InterruptedException exception) {
            log.error("tryLock error lockKey[{}] waitTime[{}]", lockKey, waitTime, exception);
            return false;
        }
    }

    /**
     * @param lockKey:分布式锁key
     * @param waitTime:锁等待时间
     * @return boolean 返回结果
     * @description 尝试获取锁，waitTime时间内获取到返回true,获取失败返回false
     */
    public static boolean tryLock(String lockKey, long waitTime, long leaseTime) {
        try {
            log.info("tryLock lockKey[{}] waitTime[{}], leaseTime[{}]", lockKey, waitTime, leaseTime);
            boolean result = lock.tryLock(lockKey, waitTime, leaseTime, TimeUnit.SECONDS);
            log.info("tryLock lockKey[{}] waitTime[{}] result[{}]", lockKey, waitTime, result);
            return result;
        } catch (InterruptedException exception) {
            log.error("tryLock error lockKey[{}] waitTime[{}]", lockKey, waitTime, exception);
            return false;
        }
    }

    /**
     * @param lockKey: 分布式锁key
     * @return boolean 返回结果
     * @description 释放锁
     */
    public static boolean unlock(String lockKey) {
        try {
            log.info("unlock lockKey[{}] ", lockKey);
            lock.unlock(lockKey);
            return true;
        } catch (Exception exception) {
            log.error("unlock error lockKey[{}] ", lockKey, exception);
            return false;
        }
    }
}
